﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Direction = LowLevelGraphics.Filter.Contours.Direction;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// This needs a monochrome bitmap to work. 
    /// Default is that the boundary will be shown in green
    /// 
    /// B = bwtraceboundary(BW, P,fstep) traces the outline of an object in binary image bw.
    /// Nonzero pixels belong to an object and 0 pixels constitute the background. 
    /// P is a two-element vector specifying the row and column coordinates of the point on the object boundary 
    /// where you want the tracing to begin.
    /// 
    /// fstep is a string specifying the initial search direction for the next object pixel connected to P. 
    /// You use strings such as 'N' for north, 'NE' for northeast, to specify the direction. 
    /// The following figure illustrates all the possible values for fstep.
    /// </summary>
    public class bwtraceboundary : BaseForeBackgroundColorFilter
    {
        protected Direction m_Direction = null;
        protected BaseForeBackgroundColorFilter filter = new BlackWhitePerimeter();

        /// <summary>
        /// Initializes a new instance of the <see cref="bwtraceboundary"/> class.
        /// </summary>
        public bwtraceboundary()
        {
            this.m_ColorForeground = Definitions.Green;
        }

        /// <summary>
        /// Gets or sets the direction.
        /// </summary>
        /// <value>The direction.</value>
        public Direction Direction
        {
            get { return m_Direction; }
            set { m_Direction = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="bwtraceboundary"/> class.
        /// </summary>
        /// <param name="_bwtraceboundary">The _bwtraceboundary.</param>
        internal bwtraceboundary(bwtraceboundary _bwtraceboundary)
        {
            m_ColorForeground = _bwtraceboundary.m_ColorForeground;
            m_ColorBackground = _bwtraceboundary.m_ColorBackground;
            m_Direction = _bwtraceboundary.m_Direction;
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmapCloned = (UnsafeBitmap)_bitmap.Clone();

            filter.Execute(bitmapCloned);

            int x = 0;
            int y=0;
            int nWidth = _bitmap.Width;
            int nHeight = _bitmap.Height;
            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    if (bitmapCloned.GetPixel(x, y) == filter.Foreground)
                    {
                        _bitmap.SetPixel(x, y,  m_ColorForeground);
                    }
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new bwtraceboundary(this);
        }
    }
}
